//---------------------------------------------------------------------------------------------
//  Copyright 2009 Jeremy Palenchar
//  http://identitynotes.palenchar.net
//
//  This file is part of Example Speech Server Password Reset.
//
//  Example Speech Server Password Reset is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  Example Speech Server Password Reset is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with Example Speech Server Password Reset.  If not, see <http://www.gnu.org/licenses/>.
//--------------------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SpeechServer.Dialog;
using Microsoft.ResourceManagement.Samples.ResourceManagementClient;
using Microsoft.ResourceManagement.Samples.ResourceManagementClient.ResourceManagement;
using Microsoft.ResourceManagement.Samples.ResourceManagementClient.Utilities;

namespace IdentityNotes.Examples.SpeechServer.PasswordReset
{
    public sealed partial class Workflow1: SpeechSequentialWorkflowActivity
    {
        
        
        public Workflow1()
        {
            InitializeComponent();
        }

        private int invalidEmployeeNumberCount = 0;
        private int invalidInformationCount = 0;
        private bool invalidZipEntered = false;
        private bool invalidDepositEntered = false;
        private bool missingKeyField = false;
        private string homeZip;
        private string directDeposit;
        private ResourceManagementObject personResource = null;

        /// <summary>
        /// This method is called when any exception other than a CallDisconnectedException occurs within the workflow.
        /// It does some generic exception logging, and is provided for convenience during debugging;
        /// you should replace or augment this with your own error handling code.
        /// CallDisconnectedExceptions are handled separately; see HandleCallDisconnected, below.
        /// </summary>
        private void HandleGeneralFault(object sender, EventArgs e)
        {
            // The fault property is read only.  When an exception is thrown the actual exception is 
            // stored in this property.  Check this value for error information.
            string errorMessage = this.generalFaultHandler.Fault is System.Reflection.TargetInvocationException && this.generalFaultHandler.Fault.InnerException != null ?
                   this.generalFaultHandler.Fault.InnerException.Message : this.generalFaultHandler.Fault.Message;

            LogError(errorMessage);
        }

        /// <summary>
        /// This method is called when a CallDisconnectedException occurs in the workflow.
        /// This happens when a speech activity tried to run while the call is not connected,
        /// and can happen for two reasons:
        /// (1) The user hung up on the app in the middle of the flow.  This is expected and normal.
        /// (2) You disconnected the call locally, and then attempted to run a speech activity.
        ///     This is an application bug, and so we break if the debugger is already attached.
        /// </summary>
        private void HandleCallDisconnected(object sender, EventArgs e)
        {
            if (((CallDisconnectedException) callDisconnectedHandler.Fault).LocalInitiation && Debugger.IsAttached)
            {
                LogError(callDisconnectedHandler.Fault.Message);
            }
        }

        /// <summary>
        /// Logs an application error and breaks into the debugger (if already attached).
        /// </summary>
        private void LogError(string errorMessage) 
        {
            if(Debugger.IsAttached)
            {
                // If the debugger is attached, break here so that you can see the error that occurred.
                // (Check the errorMessage variable.)
                Debugger.Break();
            }

            // Write the error to both the NT Event Log and the .etl file, so that some record is kept 
            // even if the debugger is not attached. The first parameter is an event id, chosen arbitrarily.
            // Microsoft Office Communication Server 2007, Speech Server uses various IDs below 50000, 
            // so you might want to use IDs above this number to avoid overlap.
            TelephonySession.LoggingManager.LogApplicationError(
                    50000,  
                    string.Format(System.Globalization.CultureInfo.CurrentCulture,
                    "An exception occurred in the Speech workflow with Id {0}. The exception was: {1}",  
                    this.WorkflowInstanceId, errorMessage));

            // Dump a detailed version of the most recent server logs to the .etl file
            // (see the 'Speech Server Administrator Console' for your current logging settings, 
            // including the location of this file)
            this.TelephonySession.LoggingManager.DumpTargetedLogs();
        }

        private void GetResource_ExecuteCode(object sender, EventArgs e)
        {
            
            WSEnumerationClient enumerationClient = new WSEnumerationClient();
            enumerationClient.ClientCredentials = new System.Net.NetworkCredential("auto", "Pass@word1", "litware");
            enumerationClient.Enumerate("/Person[EmployeeID='" + this.GetEmployeeNumber.RecognitionResult.Text.Replace(" ", null) + "']");
            //enumerationClient.Enumerate("/Person[EmployeeID='53212']");

            while (enumerationClient.IsContextValid)
            {
                if (enumerationClient.Count != 1)
                {
                    invalidEmployeeNumberCount++;
                    return;
                }
                else
                {
                    invalidEmployeeNumberCount = 0;
                    foreach (ResourceManagementObject person in enumerationClient.Pull())
                    {
                        this.personResource = person;

                        if (person["HomeZip"] != null)
                        {
                            this.homeZip = person["HomeZip"].AttributeSingleValue as string;
                            this.homeZip = this.homeZip.Trim().Substring(0, 5);
                        }
                        else
                        {
                            this.missingKeyField = true;
                            return;
                        }

                        if (person["DirectDeposit"] != null)
                        {
                            this.directDeposit = person["DirectDeposit"].AttributeSingleValue as string;
                            this.directDeposit = this.directDeposit.Trim().Substring(0, 4);
                        }

                        else
                        {
                            this.missingKeyField = true;
                            return;
                        }
                    }
                }
            }
        }

        private void CheckZipCode_ExecuteCode(object sender, EventArgs e)
        {
            string enteredZip = this.GetZip.RecognitionResult.Text.Replace(" ",null);

            if (enteredZip != this.homeZip)
            {
                this.invalidInformationCount++;
                this.invalidZipEntered = true;
            }
            else
                this.invalidZipEntered = false;

        }

        private void CheckDirectDeposit_ExecuteCode(object sender, EventArgs e)
        {
            string enteredDirectDeposit = this.GetDirectDeposit.RecognitionResult.Text.Replace(" ", null);

            if (enteredDirectDeposit != this.directDeposit)
            {
                this.invalidInformationCount++;
                this.invalidDepositEntered = true;
            }
            else
                this.invalidDepositEntered = false;
        }

        private void ResetPassword_ExecuteCode(object sender, EventArgs e)
        {
            WSTransferClient transferClient = new WSTransferClient();
            transferClient.ClientCredentials = new System.Net.NetworkCredential("auto", "Pass@word1", "litware");

            if (personResource["ResetADPasswordFlag"] == null)
            {
                personResource["ResetADPasswordFlag"] = new ResourceManagementAttribute(false, "ResetADPasswordFlag");
            }

            personResource["ResetADPasswordFlag"].ReplaceAttributeSingleValue(true);

            transferClient.Put(personResource);

        }


    }

    /// <summary>
    /// A simplified version of the one from Visual Studio's test suite.
    /// </summary>
    public sealed class Assert
    {

        internal static void IsTrue(bool testBool)
        {
            if (testBool == false)
                throw new Exception();
        }

        internal static void IsNotNull(Object testObject)
        {
            if (testObject == null)
                throw new Exception();
        }

        internal static void IsFalse(bool testBool)
        {
            IsTrue(!testBool);
        }
    }
}
